// XMLReader.java - read an XML document.
// http://www.saxproject.org
// Written by David Megginson
// NO WARRANTY!  This class is in the Public Domain.
// $Id: XMLReader.java,v 1.9 2004/04/26 17:34:34 dmegginson Exp $

package org.xml.sax;

import java.io.IOException;


/**
 * 使用回调来读取XML文档的接口。
 *XMLReader是XML解析器的SAX2驱动程序必须实现的接口。
 *该接口允许应用程序设置和查询解析器中的特性和属性，
 * 注册用于文档处理的事件处理程序，并启动文档解析。
 *
 * 所有的SAX接口都假定是同步的:
 * 在解析完成之前，{@link #parse parse} 方法一定不能返回，
 * 读者在报告下一个事件之前必须等待事件处理程序的回调。
 *
 * SAX1解析器转与SAX2 XMLReader可以互相转化：
 * org.xml.sax.helpers.XMLReaderAdapter：将SAX2 XMLReader调整为SAX1解析器。
 * org.xml.sax.helpers.ParserAdapter：将SAX1解析器作为SAX2 XMLReader进行调整。
 *
 * @version 2.0.1+ (sax2r3pre1)
 * @see org.xml.sax.XMLFilter
 * @see org.xml.sax.helpers.ParserAdapter
 * @see org.xml.sax.helpers.XMLReaderAdapter
 */
public interface XMLReader
{


    ////////////////////////////////////////////////////////////////////
    // 配置.
    ////////////////////////////////////////////////////////////////////


    /**
     * XMLReader可以识别特征名称，但暂时无法返回其值.
     * 某些特征值可能仅在特定上下文中可用，例如在解析之前，之中或之后,
     * 此外，某些功能值可能无法以编程方式访问,
     * Also, some feature values may not be programmatically accessible.
     * 此外，某些功能值可能无法以编程方式访问.
     * （在SAX1适配器的情况下，没有独立于实现的方法来暴露底层解析器是否执行验证，扩展外部实体等等。)
     * 所有的XMLReader都需要识别:
     * http://xml.org/sax/features/namespaces
     * http://xml.org/sax/features/namespace-prefixes</p>
     *
     * 典型的用法是这样的：
     * <pre>
     * XMLReader r = new MySAXDriver();
     *
     *                         // try to activate validation
     * try {
     *   r.setFeature("http://xml.org/sax/features/validation", true);
     * } catch (SAXException e) {
     *   System.err.println("Cannot activate validation.");
     * }
     *
     *                         // register event handlers
     * r.setContentHandler(new MyContentHandler());
     * r.setErrorHandler(new MyErrorHandler());
     *
     *                         // parse the first document
     * try {
     *   r.parse("http://www.foo.com/mydoc.xml");
     * } catch (IOException e) {
     *   System.err.println("I/O exception reading XML document");
     * } catch (SAXException e) {
     *   System.err.println("XML exception reading document.");
     * }
     * </pre>
     *
     *实现者可以免费（并鼓励）使用自己的URI构建自己的特性
     * @param name 功能名称，这是一个完全合格的URI。
     * @return 功能的当前值（true或false）。
     * @exception org.xml.sax.SAXNotRecognizedException 如果特征值不能被分配或检索。
     * @exception org.xml.sax.SAXNotSupportedException XMLReader识别功能名称，但目前无法确定其值。
     * @see #setFeature
     */
    public boolean getFeature (String name)
        throws SAXNotRecognizedException, SAXNotSupportedException;


    /**
     *XMLReader可能会公开一个特征值，但无法更改当前值。
     * 某些特征值只能在特定上下文中不可变或可变，例如在解析之前，之中或之后。 </p>
     *
     *所有XMLReader都需要支持设置：
     * http://xml.org/sax/features/namespaces to true
     * http://xml.org/sax/features/namespace-prefixes to false
     *
     * @param name 功能名称，这是一个完全合格的URI。
     * @param value The requested value of the feature (true or false).
     * @exception org.xml.sax.SAXNotRecognizedException 如果特征值不能被分配或检索
     * @exception org.xml.sax.SAXNotSupportedException 当XMLReader识别功能名称但不能设置请求的值时。
     * @see #getFeature
     */
    public void setFeature (String name, boolean value)
    throws SAXNotRecognizedException, SAXNotSupportedException;


    /**
     * 查找一个属性的值
     *XMLReader可能会识别属性名称，但暂时无法返回其值。
     * 某些属性值只能在特定的上下文中使用，比如在解析之前，之中或之后。
     *
     * XMLReaders不需要识别任何特定的属性名称，尽管SAX2中有一个初始的核心集合。
     *
     * 实现者可以免费（并鼓励）使用自己的URI构建自己的属性
     * @param name 属性名称，它是完全限定的URI。
     * @return 指定属性的当前值
     * @exception org.xml.sax.SAXNotRecognizedException 如果属性值不能被分配或检索。
     * @exception org.xml.sax.SAXNotSupportedException 当XMLReader识别属性名称，但目前无法确定其值。
     * @see #setProperty
     */
    public Object getProperty (String name)
    throws SAXNotRecognizedException, SAXNotSupportedException;


    /**
     * 设置一个属性的值。
     *此方法也是设置扩展处理程序的标准机制。
     * @param name 属性名称，它是完全限定的URI。
     * @param value 指定属性需要的值
     * @exception org.xml.sax.SAXNotRecognizedException 如果属性值不能被分配或检索。
     * @exception org.xml.sax.SAXNotSupportedException 当XMLReader识别属性名称但不能设置请求的值时。
     */
    public void setProperty (String name, Object value)
    throws SAXNotRecognizedException, SAXNotSupportedException;



    ////////////////////////////////////////////////////////////////////
    // 事件处理程序。
    ////////////////////////////////////////////////////////////////////


    /**
     * 允许应用程序注册实体解析器。
     *
     * 如果应用程序没有注册实体解析器，则XMLReader将执行其自己的默认解析。
     *应用程序可以在解析中注册一个新的或不同的解析器，SAX解析器必须立即开始使用新的解析器。
     * @param resolver 实体解析器。
     * @see #getEntityResolver
     */
    public void setEntityResolver (EntityResolver resolver);


    /**
     * Return the current entity resolver.
     *
     * @return The current entity resolver, or null if none
     *         has been registered.
     * @see #setEntityResolver
     */
    public EntityResolver getEntityResolver ();


    /**
     * 允许应用程序注册一个DTD事件处理程序。
     *
     * 如果应用程序没有注册DTD处理程序，那么SAX解析器报告的所有DTD事件将被忽略。
     *
     * 应用程序可以在解析中注册一个新的或不同的处理程序，SAX解析器必须立即开始使用新的处理程序。
     *
     * @param handler The DTD handler.
     * @see #getDTDHandler
     */
    public void setDTDHandler (DTDHandler handler);


    /**
     * 返回当前的DTD处理程序。
     * @return 当前的DTD处理程序，如果没有注册，则返回null。
     * @see #setDTDHandler
     */
    public DTDHandler getDTDHandler ();


    /**
     * 允许应用程序注册一个内容事件处理程序。
     *如果应用程序没有注册内容处理程序，那么SAX解析器报告的所有内容事件都将被忽略。
     * 应用程序可以在解析中注册一个新的或不同的处理程序，SAX解析器必须立即开始使用新的处理程序。
     * @param handler 内容处理程序。
     * @see #getContentHandler
     */
    public void setContentHandler (ContentHandler handler);


    /**
     *返回当前的内容处理程序
     * @return 当前内容处理程序，如果没有注册，则返回null
     * @see #setContentHandler
     */
    public ContentHandler getContentHandler ();


    /**
     * 允许应用程序注册错误事件处理程序。
     *如果应用程序没有注册错误处理程序，那么SAX解析器报告的所有错误事件将被忽略;
     * 但是，正常的处理可能不会继续。
     *
     * 强烈建议所有SAX应用程序都实现错误处理程序以避免意外的错误。
     *
     * 应用程序可以在解析中注册一个新的或不同的处理程序，SAX解析器必须立即开始使用新的处理程序。
     * @param handler The error handler.
     * @see #getErrorHandler
     */
    public void setErrorHandler (ErrorHandler handler);


    /**
     * 返回当前的错误处理程序。
     * @return 当前错误处理程序，如果没有注册，则返回null。
     * @see #setErrorHandler
     */
    public ErrorHandler getErrorHandler ();



    ////////////////////////////////////////////////////////////////////
    // 解析ing.
    ////////////////////////////////////////////////////////////////////

    /**
     *解析一个XML文档。
     *应用程序可以使用此方法指示XML阅读器开始从任何有效的输入源（字符流，字节流或URI）解析XML文档。
     *
     * 当解析正在进行时，应用程序可能不会调用这个方法（它们应该为每个嵌套的XML文档创建一个新的XMLReader）。
     *解析完成后，应用程序可能会重用相同的XMLReader对象，可能会使用不同的输入源。
     * 除非配置的该方面的定义明确指定了其他行为，否则XMLReader对象的配置（例如为特征标志和属性建立的处理程序绑定和值）不会被修改。
     * （例如，特征标志或属性暴露了正在分析的文档的特征。）
     * 在解析过程中，XMLReader将通过注册的事件处理程序提供有关XML文档的信息。
     *
     * 这个方法是同步的：直到解析结束才会返回。
     * 如果客户端应用程序想要尽早终止分析，则应该抛出异常。
     *
     *
     * @param input XML文档顶层的输入源。
     * @exception org.xml.sax.SAXException 任何SAX异常，可能包装另一个异常。
     * @exception java.io.IOException 解析器的IO异常，可能来自应用程序提供的字节流或字符流。
     * @see org.xml.sax.InputSource
     * @see #parse(java.lang.String)
     * @see #setEntityResolver
     * @see #setDTDHandler
     * @see #setContentHandler
     * @see #setErrorHandler
     */
    public void parse (InputSource input)
    throws IOException, SAXException;


    /**
     * 从系统标识符（URI）解析XML文档。
     *
     * 此方法是从系统标识符读取文档的常见情况的捷径。
     *等效于：
     * <pre>
     * parse(new InputSource(systemId));
     * </pre>
     *
     *如果系统标识符是一个URL，那么在传递给解析器之前，它必须由应用程序完全解析
     * @param systemId 系统标识符（URI）
     * @exception org.xml.sax.SAXException 任何SAX异常，可能包装另一个异常
     * @exception java.io.IOException 解析器的IO异常，可能来自应用程序提供的字节流或字符流。
     * @see #parse(org.xml.sax.InputSource)
     */
    public void parse (String systemId)
    throws IOException, SAXException;

}
